﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class CharacterMovement
{
    public Dictionary<CollisionFloor, CollisionFloor> dicCollisionFloor = new Dictionary<CollisionFloor, CollisionFloor>();
    List<CollisionFloor> lstRemove = new List<CollisionFloor>();

    Vector2[] originBottomSphere = new Vector2[2];

    public void Reset()
    {
        dicCollisionFloor.Clear();
    }

    public void AddDownMove(CollisionFloor collisionFloor)
    {
        if (dicCollisionFloor.ContainsKey(collisionFloor) == false)
        {
            collisionFloor.bDown = true;
            dicCollisionFloor.Add(collisionFloor, collisionFloor);
        }
    }

    bool IsCollSphereGap( Vector3 a, Vector3 b, float gap )
    {
        return Vector3.Distance(a, b) < gap;
    }

    public bool HorizonMove(Character character, MoveDirection dir, float fDT)
    {
        float speed = 100.0f;
        CollisionFloor collisionFloor = character._collisionFloor;

        if (collisionFloor.bDown)
            return false;

        Vector2 coll2dCoord = Vector2.zero;
        CollState[] collStatus = new CollState[2];
        int collHeight = 0;
        int curStage = 0;

        for (int i = 0; i < 2; ++i)
            originBottomSphere[i] = collisionFloor._BottomSphere[i].center;

        Vector3 movePos = character._collisionFloor._direction * (fDT * (float)dir) * speed;
        

        for (int i = 0; i < 2; ++i)
        {
            
            collisionFloor._BottomSphere[i].center += movePos;
            //character._testSphere[i].transform.localPosition += movePos;

            collStatus[i] = WorldmapDataMgr.GetPixelHeight(0, collisionFloor._BottomSphere[i].center, collisionFloor._BottomSphere[i].radius, ref collHeight);

            if (collStatus[i] == CollState.success)
            {
                collisionFloor._bCollision[i] = true;
                collisionFloor._BottomSphere[i].center = new Vector3(collisionFloor._BottomSphere[i].center.x, collHeight, 0.0f);
                //character._testSphere[i].transform.localPosition = new Vector3(collisionFloor._BottomSphere[i].center.x, collHeight, 0.0f);
            }
            else if (collStatus[i] == CollState.fail)
            {
                collisionFloor.DownBottomCollision(i, movePos);
            }
        }
                
        if ((movePos.x < 0 && movePos.y > 0.3f && collisionFloor._bCollision[0] == false) ||
            (movePos.x > 0 && movePos.y > 0.3f && collisionFloor._bCollision[1] == false) ||
            collStatus[0] == CollState.blocked || collStatus[1] == CollState.blocked)

        {
            for (int i = 0; i < 2; ++i)
            {
                collisionFloor._BottomSphere[i].center = originBottomSphere[i];
                //character._testSphere[i].transform.localPosition = originBottomSphere[i];
            }
        }

        if (collStatus[0] == CollState.fail && collStatus[1] == CollState.fail)
        {
            AddDownMove(collisionFloor);
            return false;
        }
        else
        {
            SetTrans(collisionFloor, dir);
        }

        return true;
    }


    void SetTrans(CollisionFloor collisionFloor, MoveDirection dir = MoveDirection.none)
    {
        Vector3 totalPos;
        float collTocolldist = collisionFloor.GetGapDistance();
        totalPos = collisionFloor.GetPosition();
        
        // 두 충돌체가 모두 충돌 하였을때.
        if (collisionFloor._bCollision[0] && collisionFloor._bCollision[1])
        {
            collisionFloor.UpdateDirection(dir);

        }        
        // 화면 아래로 나갔을경우.
        //else if()
        //{

        //} 


        collisionFloor._gameObj.transform.localPosition = totalPos;

        
        
    }

    public void UpdateDownMove( float fDT )
    {
        Vector2 downForce = new Vector3( 0.0f, -fDT * 100.0f);
        lstRemove.Clear();

        foreach (KeyValuePair<CollisionFloor, CollisionFloor> kvp in dicCollisionFloor)
        {
            CollisionFloor collisionFloor = kvp.Value;
            DownMove(collisionFloor, downForce);            
            
        } // end foreach.

        foreach (CollisionFloor collFloor in lstRemove)
        {
            collFloor.Reset();
            dicCollisionFloor.Remove(collFloor);
        }

    }

    void DownMove(CollisionFloor collisionFloor, Vector3 addPos)
    {
        Vector2 coll2dCoord = Vector2.zero;
        int collHeight = 0;
        int curStage = 0;
        CollState collStatus = CollState.fail;

        for (int i = 0; i < 2; ++i)
        {
            if (collisionFloor._bCollision[i] == false)
            {
                collStatus = WorldmapDataMgr.GetPixelHeight(0, collisionFloor._BottomSphere[i].center, collisionFloor._BottomSphere[i].radius, ref collHeight);
                if (collStatus == CollState.success)
                {
                    collisionFloor._bCollision[i] = true;
                    collisionFloor._BottomSphere[i].center = new Vector2(collisionFloor._BottomSphere[i].center.x, collHeight);

//                     if (collisionFloor._bCollision[i == 0 ? 1 : 0] && collisionFloor.GetGapDistance() > collisionFloor._radius * 2)
//                     {
//                         collisionFloor._bCollision[i] = true;
//                     }
                    
                }                
                else
                {
                    collisionFloor._bCollision[i] = false;
                    collisionFloor._BottomSphere[i].center += addPos;

                }

                //   Debug.Log("left :" + collisionFloor._leftBottomSphere.center.ToString());
            }
        }
        SetTrans(collisionFloor);

        if (collisionFloor._bCollision[0] && collisionFloor._bCollision[1])
            lstRemove.Add(collisionFloor);
    }
}
